package com.fingard.dsp.bank.directbank.hzcb01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptData;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptDataHelper;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directConfig.ReceiptProConfig;
import com.fingard.dsp.bank.directConfig.TaskTimerSet;
import com.fingard.dsp.bank.directbank.bankInterface.IScheduleTask;
import com.fingard.dsp.bank.reqrespobj.enumeration.ENReceiptState;
import com.fingard.dsp.bank.sepro.ReceiptPro;
import com.fingard.dsp.task.DelayCounter;
import com.fingard.io.FileHelper;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;
import com.fingard.util.PdfGenerateUtil;
import com.fingard.util.ZipHelper;
import com.fingard.FGBiz;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Parker on 2020-06-03.
 * @version 1.0
 */
public class HZCB01ScheduleTask extends HZCB01Base implements IScheduleTask {
    private String logCode = "HZCB01" + File.separator + "TaskReceiptPro";
    private TaskTimerSet timer;
    private ReceiptProConfig proConfig;
    private static DelayCounter delayCounter = new DelayCounter(45, 2);//最大延时45分钟，按平方计算，即4次=4*4=16分钟

    public static void resetDelayCounter() {
        delayCounter.resetZeroCount();
    }

    @Override
    public void execTask(TaskTimerSet timerSet) {
        try {
            if (timerSet.taskNameList.toLowerCase().contains("downreceiptpro")) {
                timer = timerSet;
                proConfig = ReceiptPro.getReceiptProConfig();
                downReceipt();
            }
        } catch (Exception e) {
            FGBiz.logTrace.exception(logCode, e);
        }
    }

    private void downReceipt() {
        SftpPortClient sftpPortClient = null;
        try {
            String saveDirPathTemp = proConfig.localSaveMainDir + File.separator + bankFront.bankCode + File.separator + "ZIP";
            if (!FileHelper.existFile(saveDirPathTemp)) {
                FileHelper.mkdir(saveDirPathTemp);
            }

            FtpSet ftpSet = bankFront.getFtpSet("receipt");
            ftpSet.downDir = StringHelper.trimEnd(ftpSet.downDir, "/") + "/";
            WriteBankLogLn("SFTP下载地址" + ftpSet.serverIP + ":" + ftpSet.port);
            WriteBankLogLn("开始遍历服务器文件目录" + ftpSet.downDir);
            sftpPortClient = new SftpPortClient(ftpSet);
            ArrayList<String> ftpFileList = sftpPortClient.listNames(ftpSet.downDir);
            if (ftpFileList.size() < 1) {
                WriteBankLogLn("无回单文件");
            } else {
                sftpPortClient.downloadFile(ftpSet.downDir, saveDirPathTemp, true);
            }
            //if (ftpReceiver.isCompleted) {
            File tmpFile = new File(saveDirPathTemp);
            File[] files = tmpFile.listFiles();
            for (File file : files) {
                if (file.getName().endsWith(".zip") || file.getName().endsWith(".ZIP")) {
                    String zipFile = saveDirPathTemp + File.separator + file.getName();
                    WriteBankLogLn("开始解压文件:" + zipFile);
                    try{
                        ZipHelper.unzipFile(zipFile, proConfig.localSaveMainDir + File.separator + bankFront.bankCode + File.separator + "UNZIP");
                        WriteBankLogLn("文件解压已完成.");
                    }catch (Exception ex){
                        WriteBankLogLn("文件解压出现异常, 请检查压缩文件是否已损坏");
                    }
                    File depressDir = new File(saveDirPathTemp);
                    File[] deFiles = depressDir.listFiles();
                    if (deFiles == null || deFiles.length <= 0) {
                        WriteBankLogLn("解压后文件夹" + saveDirPathTemp + "下为空");
                    }
                    String tmpZIP = proConfig.localSaveMainDir + File.separator + bankFront.bankCode + File.separator + "tmpZIP";
                    WriteBankLogLn("正在备份压缩文件:" + file.getName() + "至" + tmpZIP);
                    int result = FileHelper.copyFile(saveDirPathTemp + File.separator + file.getName(), tmpZIP + File.separator + file.getName());
                    if (result == 0 || result == 1) {
                        FileHelper.deleteFileIfExists(saveDirPathTemp + File.separator + file.getName());
                    }
                }
                // }
            }
            getPdfFiles(proConfig, proConfig.localSaveMainDir + File.separator + bankFront.bankCode + File.separator + "UNZIP");
            FileHelper.deleteRecursive(proConfig.localSaveMainDir + File.separator + bankFront.bankCode + File.separator + "UNZIP");
        } catch (Exception ex) {
            ex.printStackTrace();
            WriteBankLogLn(ex);
        } finally {
            if (sftpPortClient != null) {
                try {
                    sftpPortClient.disconnect();
                } catch (Exception ex) {
                    ex.printStackTrace();
                    WriteBankLogLn(ex);
                }
            }
        }
    }

    /**
     * 公共方法，下载的日期目录中提取pdf文件
     */
    protected void getPdfFiles(ReceiptProConfig pConfig, String pReceiptDir) {
        ReceiptDataHelper receiptHelper = null;//回单数据保存类，分区分表
        try {
//            receiptHelper = new ReceiptDataHelper(pReqReceipt.reqHeader.tenant, pOneDay);
            File receiptDir = new File(pReceiptDir);

            int[] retVals = getPdfLoop(pConfig, receiptDir);
            //[0]总数 [1]新增 [2]已存在
            WriteBankLogLn("目录" + pReceiptDir + "\r\n遍历总数" + retVals[0] + "，新增" + retVals[1] + "条，已存在" + (retVals[0] - retVals[1]) + "条");
        } catch (Exception ex) {
            this.WriteBankLogLn(ex);
        } finally {
            if (receiptHelper != null) {
                receiptHelper.close();
            }
        }
    }

    /**
     * 公共方法，提取pdf文件，农行是所有账号的回单一起提供，遍历所有pdf
     * [0]总数 [1]新增 [2]已存在
     */
    protected int[] getPdfLoop(ReceiptProConfig pConfig, File pDir) {
        int[] retVals = new int[2];
        retVals[0] = 0;//总pdf个数
        retVals[1] = 0;//新增
        File[] files = pDir.listFiles();
        for (File eachFile : files) {
            try {
                if (eachFile.isDirectory()) {
                    int[] subVals = getPdfLoop(pConfig, eachFile);
                    retVals[0] = retVals[0] + subVals[0];
                    retVals[1] = retVals[1] + subVals[1];
                    FileHelper.deleteRecursive(eachFile.getAbsolutePath());
                }
                String[] nameAndExt = StringHelper.splitFileNameAndExt(eachFile.getName());
                if ("pdf".equalsIgnoreCase(nameAndExt[1])) {
                    retVals[0] = retVals[0] + 1;
                    //名称_回单编号_核心流水号_日期_账号
                    String[] nameSp = nameAndExt[0].split("_");
                    if (nameSp.length != 4) {
                        WriteBankLogLn("回单文件:" + eachFile.getName() + "文件名格式不符合预期");
                        continue;
                    }
                    //重命名 本地pdf回单保存父路径
                    String renameToPath = proConfig.localSaveMainDir + File.separator + bankFront.bankCode + File.separator + nameSp[1] + File.separator + nameSp[0];
                    FileHelper.mkdirsIfNotExists(renameToPath);
                    renameToPath += File.separator + eachFile.getName();
                    File destFile = new File(renameToPath);
                    boolean reResult;
                    if (destFile.exists()) {
                        reResult = true;
                    } else {
                        reResult = eachFile.renameTo(destFile);
                    }
                    if (reResult) {
                        try {
                            Date curDate = new Date();
                            //解析PDF获取回单数据
                            String[] pdfText = PdfGenerateUtil.readPDFTable(destFile.getAbsolutePath(), 1000, 800).split("\r\n");
                            if (pdfText.length < 3) {
                                //数据入库
                                String uniqueSeqId = nameSp[2];
                                ReceiptData eachData = new ReceiptData();
                                /**回单唯一标识（在银行端的唯一标识（该账号的唯一），如招行的打印实例号）*/
                                eachData.istNbr = uniqueSeqId;
                                /**回单关联号（回单编号）*/
                                eachData.receiptNo = uniqueSeqId;
                                /**业务参考号*/
                                eachData.busRef = uniqueSeqId;
                                /**银行流水号*/
                                eachData.bnkSeqNo = uniqueSeqId;
                                /**本方账号*/
                                String payAct = pdfText[2].substring(pdfText[2].indexOf("付 账号 ") + 4, pdfText[2].indexOf(" 收 账号 ")).trim();
                                String recAct = pdfText[2].substring(pdfText[2].indexOf("收 账号 ") + 4).trim();
                                if (payAct.endsWith(nameSp[0])) {
                                    eachData.ownAct = payAct;
                                    eachData.moneyWay = "1";
                                } else {
                                    eachData.ownAct = recAct;
                                    eachData.moneyWay = "2";
                                }

                                /**银行代码，如工行102*/
                                eachData.bank = banks;
                                /**线路代码（来源渠道），如工行直联ICBC02*/
                                eachData.srcSys = this.bankFront.bankCode;
                                /**日期*/
                                eachData.busDate = Integer.parseInt(nameSp[1]);
                                eachData.oppActNum = "";
                                /**对方户名*/
                                eachData.oppActName = "";
                                /**币种*/
                                eachData.cur = convertCurToATS("00");
                                //eachData.amount=new BigDecimal(0);
                                /**用途*/
                                eachData.purpose = "";
                                /**回单文件--本地文件相对路径*/
                                eachData.localFile = StringHelper.getRelativePath(renameToPath, pConfig.localSaveMainDir);
                                /**源文件路径*/
                                eachData.srcFile = renameToPath;
                                /**回单文件类型*/
                                eachData.fileType = "1";
                                /**下载状态：指从银行下载该回单文件的状态，1未下载；2已下载；3下载失败；4下载中*/
                                eachData.downState = ENReceiptState.SUCCESS.getValue();
                                /**下载时间*/
                                eachData.downTime = curDate;
                                /**下载信息，如果失败则为失败原因*/
                                eachData.downInfo = "下载成功";
                                /**上传状态：指文件从银行端下载完成后，上传至ftp或ats或oss或客制化文件服务的状态，1未上传；2已上传；3上传失败；4上传中*/
                                eachData.upState = ENReceiptState.INIT.getValue();
                                /**推送状态：指文件上传完成后，回单数据推送至ats或客制化平台的状态，1未推送；2已推送；3推送失败；4推送中*/
                                eachData.pushState = ENReceiptState.INIT.getValue();
                                ;
                                /**创建时间*/
                                eachData.createdOn = curDate;
                                /**最后修改时间*/
                                eachData.lastModifiedOn = curDate;
                                /**版本号*/
                                eachData.rowVersion = 1;
                                ReceiptDataHelper receiptHelper = new ReceiptDataHelper(reqHeader.tenant, eachData.getBusDate());
                                //回单数据记录入库
                                int inRe = receiptHelper.insertIfNotExist(eachData);
                                if (inRe > 0) {
                                    WriteBankLogLn(eachData.receiptNo + "写入数据库，影响行数：" + inRe);
                                } else {
                                    FGBiz.logTrace.info(logCode, eachData.receiptNo + "写入数据库，影响行数：" + inRe);
                                }

                            } else {
                                WriteBankLogLn("回单编号" + nameSp[2] + "对应PDF文件解析失败：\r\n" + eachFile.getAbsolutePath() + "请检查文件是否正常");
                            }
                        } catch (Exception ex) {
                            ex.printStackTrace();
                            WriteBankLogLn("回单编号" + nameSp[2] + "对应PDF文件解析失败：\r\n" + eachFile.getAbsolutePath() + "请检查文件是否正常,失败原因:" + ex.getMessage());
                        }
                    } else {
                        WriteBankLogLn("回单编号" + nameSp[2] + "重命名失败：\r\n" + eachFile.getAbsolutePath() + "\r\n重命名为：\r\n" + renameToPath);
                    }
                }
            } catch (Exception ex) {
                WriteBankLogLn(ex, eachFile.getAbsolutePath());
            }
        }
        return retVals;
    }

}
